package appcomp.entities;

import core.CodeGenerator;

public class CompositePort extends Port {

	private Port original; 
	
	private Operator o;
	
	public CompositePort(String name, Visibility vis, Connector conn, Port orig, Operator o) {
		this.original = orig;
		this.setName(name);
		portVis = vis;
		this.direction = orig.getDirection();
		this.handler = orig.handler;
		this.conn = conn;
		this.type = orig.type;
		this.o = o;
		this.index = orig.index;
	}

	/**
	 * @return the original
	 */
	public Port getOriginal() {
		return original;
	}

	/**
	 * @param original the original to set
	 */
	public void setOriginal(Port original) {
		this.original = original;
	}

	public Operator getOperator() {
	    return o;
	}
	
	public String printFullName() {
		return this.getName() + ":" + this.getDirection() + ":" + this.portVis;
	}

	/* (non-Javadoc)
	 * @see appcomp.entities.Port#generateCode(core.CodeGenerator)
	 */
	@Override
	public void generateCode(CodeGenerator cg) {
//		if(this.getDirection() == Port.Direction.IN) {
//			this.getFile().println("\tvoid " + this.handler + "(" + this.type.getCoreType() + " * data, unsigned long dataSize);");
//			this.getFile().println("\t" + this.type.getCoreType() + " * gen" + this.getName() + "Request();");
//		}
	    if(this.portVis == CompositePort.Visibility.EXTERNAL) {
	        if(this.direction == Port.Direction.OUT) {
	            super.generateCode(cg);
	        }
	        else {
	            this.getFile().println("\tvoid " + this.conn.outName.getLeft() + "_" + this.handler + "(" + this.type.getCoreType() + " * data, unsigned long dataSize) {");
	            this.getFile().println("\t\tlocal_" + this.getOperator().getName() + "." + this.handler + "(data, dataSize);");
	            this.getFile().println("\t}");
	            this.getFile().println("\t" + this.type.getCoreType() + " * gen" + this.getName() + "Request() {");
	            this.getFile().println("\t\treturn local_" + this.getOperator().getName() + ".gen" + this.getOriginal().getName() + "Request();");
	            this.getFile().println("\t}");
	        }
	    }
	    else {
	        if(this.direction == Port.Direction.OUT) {
                this.getFile().println("\tvoid " + this.getName() + "(" + this.type.getCoreType() + " * data, unsigned long dataSize) {");
                this.getFile().println("\t\t" + this.conn.outName.getLeft() + "_" + this.conn.outName.getRight() + "(data, dataSize);");
                this.getFile().println("\t}");
	        }
	        else {
                this.getFile().println("\tvoid " + this.getName() + "(" + this.type.getCoreType() + " * data, unsigned long dataSize) {");
                this.getFile().println("\t\tlocal_" + this.conn.outName.getLeft() + "." + this.handler + "(data, dataSize);");
                this.getFile().println("\t}");
	        }
	    }

	}

    /* (non-Javadoc)
     * @see appcomp.entities.Port#generateCodeCases()
     */
    @Override
    public void generateCodeCases() {
        if(this.portVis == CompositePort.Visibility.EXTERNAL) {
            this.getFile().print("\t\tif(rcon->getPort() == ");   
            this.getFile().println(this.index + ") {" + this.conn.outName.getLeft() +"_"+ this.getHandler() + "(static_cast<" + this.type.getCoreType() + " *>(rcon->getRData()), rcon->getSize());}");
            this.getFile().println();
        }
    }

    /* (non-Javadoc)
     * @see appcomp.entities.Port#generateProfCode()
     */
    @Override
    public void generateProfCode() {
        if(this.portVis == CompositePort.Visibility.EXTERNAL) {
            this.getFile().println("\t\tretList->push_back(new lagniappe::RCon(this, static_cast<lagniappe::RData *>(gen" + this.getName() + "Request()), " + this.getIndex() + "));");
        }
    }
	
	
	
}
